Skip to content

feat!: eslint-plugin-import-x 4.18 with its barrel-file rules on; patch minimatch and zod - #17

Merged
ryan-morris merged 1 commit into
mainfrom
import-x-4.18
Nov 10, 2026
Merged

ryan-morris merged 1 commit into
mainfrom
import-x-4.18

Conversation

@ryan-morris

Copy link
Copy Markdown
Member

Summary

Fixes Dependabot alert #6 (minimatch, GHSA-g3hv-75wg-m249) here, and unblocks the same fix in devenvy/ffmpeg-build (#128), where a minimatch 11 override crashed lint.

Dependencies

  • eslint-plugin-import-x ^4.18.1. 4.17.1 imports minimatch's makeRe, which minimatch 11 removed. 4.18.1 is the first release that accepts ^11.0.1.
  • Overrides in pnpm-workspace.yaml.
    • minimatch@<11.0.1 → ^11.0.1: eslint 10.14.0, @eslint/config-array and typescript-eslint still ask for ^10, and 10.x has no fix. Drop the override once they allow 11.
    • zod@<4.6.6 → ^4.6.6 (GHSA-mrhx-c7xc-m3w5, high): through knip and @angular/forms, whose ranges already allow the fix.
  • pnpm audit: no known vulnerabilities.

import-x 4.18's four new rules, all on as error

Rule Catches Why
avoid-barrel-files a module that mostly re-exports others (more than 3 exports) every importer loads all of them: slower start-up and tests, worse tree-shaking, easier cycles
avoid-importing-barrel-files importing from such a module, dependencies included (lodash-es vs lodash-es/debounce) the same cost, caught at the import
avoid-namespace-import import * as x hides which exports are used, defeats tree-shaking
avoid-re-export-all export * from the API becomes whatever another module exports; name conflicts between two export * pass silently

To meet them, with no exceptions or disables:

  • Rule tables name their object (const rules = {...}; export default rules;). The rule counted the properties of export default {...} as exports. The rules themselves are unchanged, and rules:add still appends before }); (it finds the table's last line starting with }).
  • BREAKING: @devenvy/code-guidelines/eslint exports createConfig only. It no longer re-exports the layer builders (angular, ignores, imports, javascript, prettier, typescript, vitest) or normalizeOptions. The README documents only createConfig. Every known consumer imports only that: devenvy/ffmpeg-build and this repository's own eslint.config.mjs. The tests import the layers from their own modules. Release as 4.0.0.
  • scripts/rules-add.mjs imports Prettier's format and resolveConfig by name.

Import order change consumers will see

In 4.18, order puts parent imports (../x) before sibling ones (./y) when they share a group, as ['parent', 'sibling', 'index'] does here: un-ts/eslint-plugin-import-x#517. The old comparator wasn't transitive, so a file could pass on Node 24 and fail on Node 26 with no change. Upstream eslint-plugin-import fixed it the same way. Consumers whose imports followed the old order get import-x/order reports, all autofixable (eslint --fix): devenvy/ffmpeg-build has 106. A new plain-js fixture (nested/) pins the order.

Testing

  • lint, typecheck, knip, format:check, guidelines:check: pass.
  • pnpm test, pack test included: 11 files, 142 tests pass.
  • check:package (publint, are-the-types-wrong): no new findings.
  • Effective-config snapshots: the only change is the four rules at error (2) in all five configurations.
  • Measured against devenvy/ffmpeg-build with this branch linked: 106 import-x/order reports (autofixable) and 1 avoid-barrel-files (src/cli-errors.ts), to be fixed there in #128 once this is released.

🤖 Generated with Claude Code

…ch minimatch and zod

eslint-plugin-import-x 4.18.1 is the first to accept minimatch 11, which
fixes GHSA-g3hv-75wg-m249 (Dependabot #6; 4.17.1 imports minimatch's `makeRe`,
which 11 removed). minimatch is overridden to ^11.0.1, since eslint and
typescript-eslint still ask for ^10, and zod to ^4.6.6 (GHSA-mrhx-c7xc-m3w5,
through knip and @angular/forms). pnpm audit: no known vulnerabilities.

4.18's four new rules are on as `error`:
- avoid-barrel-files: a module that mostly re-exports others makes every
  importer load all of them.
- avoid-importing-barrel-files: the same through an import, dependencies
  included.
- avoid-namespace-import: `import * as x` hides which exports are used and
  defeats tree-shaking.
- avoid-re-export-all: `export * from` makes a module's API whatever another
  module exports.

To meet them:
- The rule tables name their object (`const rules = {...}; export default
  rules;`): the rule counted the properties of `export default {...}` as
  exports. The rules are unchanged; rules:add still appends before `});`.
- BREAKING: `@devenvy/code-guidelines/eslint` exports `createConfig` only. The
  layer builders and normalizeOptions are no longer re-exported. The README
  documents only createConfig, and no known consumer imports anything else.
- scripts/rules-add.mjs imports Prettier's `format` and `resolveConfig` by
  name.

4.18's `order` now puts parent imports before sibling ones when they share a
group, as ours do (un-ts/eslint-plugin-import-x#517): the old comparator wasn't
transitive, so a file could pass on one Node version and fail on another.
Consumers whose imports followed the old order get autofixable
import-x/order reports. A new plain-js fixture pins the order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🟢 Lines 96.7% (🎯 85%) 616 / 637
🟢 Statements 96.36% (🎯 85%) 637 / 661
🟢 Functions 96% (🎯 85%) 120 / 125
🟢 Branches 88.98% (🎯 85%) 404 / 454
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/eslint/index.mjs 100% 100% 100% 100%
src/eslint/rules/angular-template.mjs 100% 100% 100% 100%
src/eslint/rules/angular.mjs 100% 100% 100% 100%
src/eslint/rules/imports.mjs 100% 100% 100% 100%
src/eslint/rules/javascript.mjs 100% 100% 100% 100%
src/eslint/rules/typescript.mjs 100% 100% 100% 100%
src/eslint/rules/vitest.mjs 100% 100% 100% 100%
Generated in workflow #27 for commit 760ff2f by the Vitest Coverage Report Action

@ryan-morris
ryan-morris merged commit e6719e9 into main Nov 10, 2026
16 checks passed
@ryan-morris
ryan-morris deleted the import-x-4.18 branch November 10, 2026 22:27
ryan-morris added a commit to devenvy/ffmpeg-build that referenced this pull request Nov 10, 2026
…g-m249) (#129)

## Summary

Follow-up to #128. It closes **Dependabot alert #1** and **code-scanning
alert #88** (Scorecard's "Vulnerabilities" check counts the same
advisory, so #88 clears on its first run after this merges).

- **minimatch < 11.0.1** (GHSA-g3hv-75wg-m249, a DoS through globparts
amplification) came in only through dev tooling: eslint 10.14.0,
`@eslint/config-array` and typescript-eslint, which still ask for `^10`.
10.x has no fix, so `pnpm-workspace.yaml` overrides it to `^11.0.1`
(resolves to 11.0.5), with a note to drop the override once they allow
11. The published package's runtime dependencies (commander, yaml, zod)
don't include minimatch.
- **That needed `@devenvy/code-guidelines` 4.0.0**
(devenvy/code-guidelines-ecma#17). Its eslint-plugin-import-x 4.18 works
with minimatch 11; 4.17 imported `makeRe`, which 11 removed.
- `pnpm audit`: no known vulnerabilities.

## What code-guidelines 4.0.0 asked for

- **`import-x/order`**: parent imports (`../x`) now come before sibling
ones (`./y`) in the shared relative group. The old comparator wasn't
transitive, so the result could depend on the Node version
(un-ts/eslint-plugin-import-x#517). `eslint --fix` reordered 106 imports
in 78 files. Checked file by file: apart from the files below, each
changed file holds exactly the same lines as before, only reordered.
- **`import-x/avoid-barrel-files`**: `src/cli-errors.ts` re-exported
`CliError`, `EXIT_PROBLEM`, `EXIT_USAGE` and `ExitCode` from
`cli-error.ts`. Its six importers take them from `cli-error.ts` now, and
the re-exports are gone.

## Testing

- `guidelines:check`, `lint`, `format:check`, `typecheck`, `knip`: pass.
- `test:ci`: 197 files, 4705 tests pass.
- **Timing note:** in one full run, a `tests/driver.test.ts` test hit
its 60 s timeout and then passed on re-run. It isn't caused by this
change: on `main`, its two slowest tests take 58 s and 55.5 s, close to
the limit, and are equally slow there. Left for a separate fix.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant